﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.Security;
using System.Security.Cryptography;
using MpSoft.Library.DAO.Customers;
using MpSoft.Library.DTO;
using MpSoft.Basic.Configuration;
using MpSoft.Basic.Utils;

namespace MpSoft.Library.BUSS.Customers
{

    #region  Customer
    public class CustomerBUSS
    {
        //private const string CUSTOMER_ALL_KEY = "Mp.customer.all-{0}}";
        //private const string CUSTOMER_BY_ID_KEY = "Mp.customer.id-{0}";

        public static int Customer_Add(Customer obj)
        {
            string saltKey = CreateSalt(5);
            string passwordHash = CreatePasswordHash(obj.PasswordHash, saltKey);
            obj.PasswordHash = passwordHash;
            obj.SaltKey = saltKey;
            obj.CustomerGUID = Guid.NewGuid();
            var result = CustomerDAO.Customer_Add(obj);
            return result;
        }
       
        public static int Customer_Update(Customer obj)
        {
            var result = CustomerDAO.Customer_Update(obj);
            return result;
        }

        public static int Customer_Delete(int CustomerID)
        {
            var result = CustomerDAO.Customer_Delete(CustomerID);
            return result;
        }
        public static int Customer_Add(string email, string password, bool IsAdmin, bool Active, out MembershipCreateStatus status)
        {
            Customer obj = null;
            status = MembershipCreateStatus.UserRejected;
            if (Customer_ByEmail(email) != null)
            {
                status = MembershipCreateStatus.DuplicateEmail;
                return -1;
            }
            if (!CommonHelper.IsValidEmail(email))
            {
                status = MembershipCreateStatus.InvalidEmail;
                return -1;
            }
            string saltKey = CreateSalt(5);
            string passwordHash = CreatePasswordHash(password, saltKey);
            obj = new Customer();
            obj.CustomerGUID = Guid.NewGuid();
            obj.Email = email;
            obj.PasswordHash = passwordHash;
            obj.SaltKey = saltKey;
            obj.IsAdmin = IsAdmin;
            obj.Active = Active;
            var customerid = Customer_Add(obj);
            if (customerid > 0)
            {
                status = MembershipCreateStatus.Success;
                return customerid;
            }
            return -1;
        }
        /// <summary>
        /// Change Password, input email + Oldpassword and NewPassword
        /// </summary>
        public static int Customer_ChangePassWord(string email, string Oldpassword, string NewPassword)
        {
            var customer = Customer_ByEmail(email);
            if (customer != null)
            {
                string oldPasswordHash = CreatePasswordHash(Oldpassword, customer.SaltKey);
                if (!customer.PasswordHash.Equals(oldPasswordHash))
                    return -1;//throw new Exception("Current Password doesn't match.");
                string newPasswordSalt = CreateSalt(5);
                string newPasswordHash = CreatePasswordHash(NewPassword, newPasswordSalt);
                customer.PasswordHash = newPasswordHash;
                customer.SaltKey = newPasswordSalt;
                if (Customer_Update(customer) > 0)
                    return 1;
            }
            return -1;
        }
        /// <summary>
        /// Active Customer if DeActive else Active
        /// </summary>
        public static int Customer_Active(int CustomerID)
        {
            var customer = Customer_ByID(CustomerID);
            if (customer != null)
            {
                customer.Active = customer.Active ? false : true;
                Customer_Update(customer);
            }
            return -1;
        }

        public static Customer Customer_ByEmail(string email)
        {
            var list = Customer_List(-1, null, email);
            if (list != null)
                return list.FirstOrDefault();
            return null;
        }
        
        public static Customer Customer_ByUserName(string username)
        {
            var list = Customer_List(-1, username, null);
            if (list != null)
                return list.FirstOrDefault();
            return null;
        }
       
        public static Customer Customer_ByID(int customerid)
        {
            var list = Customer_List(customerid, null, null);
            if (list != null)
                return list.FirstOrDefault();
            return null;
        }
        
        /// <summary>
        /// Login a customer
        /// </summary>
        public static bool Login(string username, string Password)
        {
            Customer customer = Customer_ByUserName(username);
            if (customer == null)
                return false;
            if (!customer.Active)
                throw new Exception("Account is disabled");
            if (customer.Deleted)
                throw new Exception("Account is deleted");
            string str = CreatePasswordHash(Password, customer.SaltKey);
            bool result =  customer.PasswordHash.Equals(str);
            //if (result)
            //{
                //CustomerSession registeredCustomerSession = CustomerSessionManager.GetByCustomerID(customer.CustomerID);
                //if (registeredCustomerSession != null)
                //{
                //    registeredCustomerSession.IsExpired = false;
                //    CustomerSession anonCustomerSession = NopContext.Current.Session;
                //    ShoppingCartCollection cart = ShoppingCartManager.GetCurrentShoppingCart();
                //    NopContext.Current.Session = registeredCustomerSession;
                //    if ((anonCustomerSession != null) && (anonCustomerSession.CustomerSessionGUID != registeredCustomerSession.CustomerSessionGUID))
                //        foreach (ShoppingCart item in cart)
                //        {
                //            ShoppingCartManager.AddToCart(item.ProductVariantID, item.Quantity, item.TextOption);
                //            ShoppingCartManager.DeleteShoppingCart(item.ShoppingCartID);
                //        }

                //}
                //if (MpContext.Current.Session == null)
                //    MpContext.Current.Session = MpContext.Current.GetSession(true);
                //MpContext.Current.Session.IsExpired = false;
                //MpContext.Current.Session.LastAccessed = DateTime.Now;
                //MpContext.Current.Session.CustomerID = customer.CustomerID;
                //CustomerSessionManager.SaveCustomerSession(MpContext.Current.Session.CustomerSessionGUID, MpContext.Current.Session.CustomerID, NopContext.Current.Session.LastAccessed, NopContext.Current.Session.IsExpired);
            //}
            return result;
        }
        /// <summary>
        /// Logout a customer
        /// </summary>
        public static void Logout()
        {
            MpContext.Current.ResetSession();
            if (HttpContext.Current.Session != null)
                HttpContext.Current.Session.Abandon();
            FormsAuthentication.SignOut();
        }
        public static List<Customer> Customer_List(int CustomerID, string Username, string Email)
        {
            return CustomerDAO.Customer_List(CustomerID, Username, Email);
        }
        /// <summary>
        /// Creates a password hash
        /// </summary>
        private static string CreatePasswordHash(string Password, string Salt)
        {
            return FormsAuthentication.HashPasswordForStoringInConfigFile(Password + Salt, "SHA1");
        }

        /// <summary>
        /// Creates a salt
        /// </summary>
        private static string CreateSalt(int size)
        {
            RNGCryptoServiceProvider provider = new RNGCryptoServiceProvider();
            byte[] data = new byte[size];
            provider.GetBytes(data);
            return Convert.ToBase64String(data);
        }
    }
    #endregion

}
